﻿/**

 * Copyright (c) 2015-2016, FastDev 刘强 (fastdev@163.com).

 *

 * Licensed under the Apache License, Version 2.0 (the "License");

 * you may not use this file except in compliance with the License.

 * You may obtain a copy of the License at

 *

 *      http://www.apache.org/licenses/LICENSE-2.0

 *

 * Unless required by applicable law or agreed to in writing, software

 * distributed under the License is distributed on an "AS IS" BASIS,

 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

 * See the License for the specific language governing permissions and

 * limitations under the License.

 */


using RazorEngine.Compilation;
using RazorEngine.Templating;
using RazorEngine.Text;
using System;
using System.Collections.Generic;
using System.Dynamic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Web.Mvc;
using System.Web;

namespace OF.SmartMVC.Core.Compile.Template
{
    public class SmartTemplateBase<T> : SmartTemplateBase
    { 
        private object currentModel;

        public T Model
        {
            get { return (T)currentModel; }
            set { currentModel = value; }
        }

        public override void SetModel(object model)
        {
            Model = (T)model;
        }

    }

    public abstract class SmartTemplateBase : TemplateBase, ITemplate
    {
        private Dictionary<string, Func<object, string>> funcDict = new Dictionary<string, Func<object, string>>();

        public SmartTemplateBase()
        {
            if (this.GetType().Name.IndexOf("StaticViews_SRootHead") >= 0)
            {
            }
        }
        public string FuncName
        { get; set; }

        public bool IsFunc(string funcName)
        {
            return object.Equals(this.FuncName, funcName);    
        }

        internal void DeclareFunc(string name, Func<object, string> func)
        {
            funcDict.Add(name, func);
        }

        public void CallFunc(string name, object model = null)
        {            
            Func<object, string> func = null;
            if (funcDict.TryGetValue(name, out func))
            {
                string result = func(model);
                //this.CurrentWriter.Write(result);
                WriteLiteral(result);
            }
            else
            {
                name = name;
            }
        }
        
        public void RenderPartial(string assemblyName, string viewName, 
            object model = null)
        {
            var request = new RunViewRequest
            {
                assemblyName = assemblyName,
                viewName = viewName,
                model = model
            };
            request.Html = this.Html;
            request.Url = this.Url;
            string result = EngineHelper.RunView(request);
            //this.CurrentWriter.Write(result);
            WriteLiteral(result);
        }

        public override void WriteTo(TextWriter writer, object value)
        {
            if (writer == null)
            {
                throw new ArgumentNullException("writer");
            }
            if (value == null)
            {
                return;
            }

            if (value is MvcHtmlString)
            {
                writer.Write(value);
                return;
            }

            base.WriteTo(writer, value);
        }

        public void RenderRaw(string result)
        {
            //this.CurrentWriter.Write(result);
            WriteLiteral(result);
        }

        public UrlHelper Url { get; set; }

        public HtmlHelper Html { get; set; }

        public override bool IsSectionDefined(string name)
        {
            throw new NotSupportedException();
        }

        public override TemplateWriter RenderSection(string name, bool required = true)
        {
            throw new NotSupportedException();
        }

        protected override ITemplate ResolveLayout(string name)
        {
            throw new NotSupportedException();
        }


        public override TemplateWriter Include(string name, object model, Type modelType)
        {
            throw new NotSupportedException();
        }
    }
}

 